package cn.taketoday.live.http;

import com.alibaba.fastjson.JSONObject;

import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import cn.taketoday.live.config.GlobalData;
import cn.taketoday.live.data.heart.SmallHeart;
import cn.taketoday.live.data.heart.XData;
import cn.taketoday.live.data.room.RoomInfo;
import cn.taketoday.live.tools.CurrencyTools;
import cn.taketoday.live.utils.HttpUtils;
import lombok.extern.slf4j.Slf4j;

/**
 * @author BanqiJane
 */
@Slf4j
public class HttpHeartBeatData {

  public static void httpGetHeartBeatOrS(Long timestamp) {
    String data = null;
    JSONObject jsonObject = null;
    String urlString = null;
    if (timestamp != null) {
      urlString = "https://api.live.bilibili.com/relation/v1/Feed/heartBeat?_=" + timestamp;
    }
    else {
      urlString = "https://api.live.bilibili.com/relation/v1/Feed/heartBeat";
    }
    Map<String, String> headers = null;
    headers = new HashMap<>(4);
    headers.put("user-agent",
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36");
    headers.put("referer", "https://live.bilibili.com/" + CurrencyTools.parseRoomId());
    if (!StringUtils.isEmpty(GlobalData.USERCOOKIE)) {
      headers.put("cookie", GlobalData.USERCOOKIE);
    }
    try {
      data = HttpUtils.getString(urlString, headers, null);
    }
    catch (Exception e) {

      log.error("", e);
      data = null;
    }
    if (data == null)
      return;

    jsonObject = JSONObject.parseObject(data);
    short code = jsonObject.getShort("code");
    if (code == 0) {
      if (jsonObject.getString("msg").equals("success")) {
//				LOGGER.debug("在线心跳包get发送成功"+jsonObject.getString("data"));
      }
      else {
        log.error("在线心跳包get发送失败" + jsonObject.toString());
      }
    }
    else {
      log.error("在线心跳包get发送失败" + jsonObject.toString());
    }
  }

  public static void httpPostUserOnlineHeartBeat() {
    JSONObject jsonObject = null;
    String data = null;
    Map<String, String> headers = null;
    Map<String, String> params = null;
    if (GlobalData.USER_BARRAGE_MESSAGE == null && GlobalData.COOKIE == null)
      return;
    headers = new HashMap<>(4);
    headers.put("user-agent",
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36");
    headers.put("referer", "https://live.bilibili.com/" + CurrencyTools.parseRoomId());
    if (!StringUtils.isEmpty(GlobalData.USERCOOKIE)) {
      headers.put("cookie", GlobalData.USERCOOKIE);
    }
    params = new HashMap<>(4);
    params.put("csrf_token", GlobalData.COOKIE.getBili_jct());
    params.put("csrf", GlobalData.COOKIE.getBili_jct());
    params.put("visit_id", "");
    try {
      data = HttpUtils
              .postString("https://api.live.bilibili.com/User/userOnlineHeart", headers, params);
    }
    catch (Exception e) {
      log.error("", e);
      data = null;
    }
    if (data == null)
      return;
    jsonObject = JSONObject.parseObject(data);
    short code = jsonObject.getShort("code");
    if (code == 0) {
      if (jsonObject.getString("message").equals("0")) {
//				LOGGER.debug("心跳包post发送成功" + jsonObject.getString("data"));
      }
      else {
        log.error("心跳包post发送失败,未知错误,原因未知v" + jsonObject.toString());
      }
    }
    else {
      log.error("发跳包post发送失败,未知错误,原因未知" + jsonObject.toString());
    }
  }

  /**
   * @param roomInfo
   *
   * @return
   */
  public static XData httpPostE(RoomInfo roomInfo) {
    JSONObject jsonObject = null;
    String data = null;
    Map<String, String> headers = null;
    LinkedHashMap<String, String> params = new LinkedHashMap<>();
    SmallHeart smallHeart = null;
    XData xData = null;
    StringBuilder stringBuilder = new StringBuilder(50);
    if (GlobalData.USER_BARRAGE_MESSAGE == null && GlobalData.COOKIE == null)
      return null;
    headers = new HashMap<>(4);
    headers.put("user-agent",
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36");
    headers.put("referer", "https://live.bilibili.com/" + CurrencyTools.parseRoomId());
    if (!StringUtils.isEmpty(GlobalData.USERCOOKIE)) {
      headers.put("cookie", GlobalData.USERCOOKIE);
    }
    roomInfo = HttpRoomData.httpGetRoomInfo();
    long[] ids = { roomInfo.getParent_area_id(), roomInfo.getArea_id(), 0, GlobalData.ROOM_ID };
    stringBuilder.append("[")
            .append("\"").append(CurrencyTools.deviceHash()).append("\"").append(",")
            .append("\"").append(CurrencyTools.getUUID()).append("\"").append("]");
    String devices = stringBuilder.toString();
    params = new LinkedHashMap<>(10);
    long ts = System.currentTimeMillis();
    params.put("id", Arrays.toString(ids));
    params.put("device", devices);
    params.put("ts", String.valueOf(ts));
    params.put("is_patch", "0");
    params.put("heart_beat", "[]");
    params.put("ua", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36");
    params.put("csrf_token", GlobalData.COOKIE.getBili_jct());
    params.put("csrf", GlobalData.COOKIE.getBili_jct());
    params.put("visit_id", "");
    try {
      data = HttpUtils.postString("https://live-trace.bilibili.com/xlive/data-interface/v1/x25Kn/E", headers, params);
    }
    catch (Exception e) {

      log.error("", e);
      data = null;
    }
    if (data == null)
      return null;
    jsonObject = JSONObject.parseObject(data);
    short code = jsonObject.getShort("code");
    if (code == 0) {
      if (jsonObject.getString("message").equals("0")) {
//				LOGGER.debug("心跳包post发送成功" + jsonObject.getString("data"));
        smallHeart = jsonObject.getObject("data", SmallHeart.class);
        xData = new XData(ids, devices, smallHeart.getTimestamp(), smallHeart.getSecret_key(), smallHeart.getHeartbeat_interval(), ts,
                          smallHeart.getSecret_rule(), false);
      }
      else {
        log.error("心跳包Epost发送失败,未知错误,原因未知v:" + jsonObject.toString());
      }
    }
    else {
      log.error("发跳包Epost发送失败,未知错误,原因未知:" + jsonObject.toString());
    }
    stringBuilder.delete(0, stringBuilder.length());
    return xData;
  }

  /**
   * 加密s函数方法来自 https://github.com/lkeme/bilibili-pcheartbeat
   */
  public static XData httpPostX(RoomInfo roomInfo, int num, XData xData) {
    JSONObject jsonObject = null;
    String data = null;
    Map<String, String> headers = null;
    Map<String, String> params = null;
    SmallHeart smallHeart = null;
    if (GlobalData.USER_BARRAGE_MESSAGE == null && GlobalData.COOKIE == null)
      return xData;
    headers = new HashMap<>(4);
    headers.put("user-agent",
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36");
    headers.put("referer", "https://live.bilibili.com/" + CurrencyTools.parseRoomId());
    if (!StringUtils.isEmpty(GlobalData.USERCOOKIE)) {
      headers.put("cookie", GlobalData.USERCOOKIE);
    }
    params = new HashMap<>(12);
    roomInfo = HttpRoomData.httpGetRoomInfo();
    long[] ids = { roomInfo.getParent_area_id(), roomInfo.getArea_id(), num, GlobalData.ROOM_ID };
//		String[] devices = {CurrencyTools.deviceHash(),CurrencyTools.getUUID()};
    long ts = System.currentTimeMillis();
    xData.setId(ids);
    params.put("s", HttpOtherData.httpPostencS(xData, ts));
    params.put("id", Arrays.toString(ids));
    params.put("device", xData.getDevice());
    params.put("ets", xData.getEts().toString());
    params.put("benchmark", xData.getBenchmark());
    params.put("time", xData.getTime().toString());
    params.put("ts", String.valueOf(ts));
    params.put("ua", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36");
    params.put("csrf_token", GlobalData.COOKIE.getBili_jct());
    params.put("csrf", GlobalData.COOKIE.getBili_jct());
    params.put("visit_id", "");
    try {
      data = HttpUtils
              .postString("https://live-trace.bilibili.com/xlive/data-interface/v1/x25Kn/X", headers, params);
    }
    catch (Exception e) {

      log.error("", e);
      data = null;
    }
    if (data == null)
      return xData;
    jsonObject = JSONObject.parseObject(data);
    short code = jsonObject.getShort("code");
    if (code == 0) {
      if (jsonObject.getString("message").equals("0")) {
//				LOGGER.debug("心跳包post发送成功" + jsonObject.getString("data"));
        smallHeart = jsonObject.getObject("data", SmallHeart.class);
        xData.setTs(ts);
        xData.setBenchmark(smallHeart.getSecret_key());
        xData.setEts(smallHeart.getTimestamp());
        xData.setSecret_rule(smallHeart.getSecret_rule());
        xData.setTime(smallHeart.getHeartbeat_interval());
        xData.setError(false);
      }
      else {
        log.error("心跳包Xpost发送失败,未知错误,原因未知v:" + jsonObject.toString());
        xData.setError(true);
      }
    }
    else {
      log.error("发跳包Xpost发送失败,未知错误,原因未知:" + jsonObject.toString());
      xData.setError(true);
    }
    return xData;
  }
}
